/*******************************************************************************
 * Copyright (c) 2005 Ultimania Organization. All rights reserved. This program
 * and the accompanying materials are made available under the terms of the
 * Eclipse Public License v1.0 which accompanies this distribution, and is
 * available at http://www.eclipse.org/org/documents/epl-v10.html
 * 
 * Contributors: tidus - initial implementation.
 ******************************************************************************/

package org.ultimania.middlegenide.core;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.Driver;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Properties;
import java.util.ResourceBundle;

public class DatabaseInfo {
	private String uri = "";

	private String user = "";

	private String password = "";

	private String catalog = "";

	private String schema = "";

	private Driver driver = null;

	private boolean enableView = false;

	private String productName = null;

	final public String POSTGRESQL = "PostgreSQL";

	final public String MYSQL = "MySQL";

	final public String HSQLDB = "HSQL Database Engine";

	final public String DERBY = "Apache Derby";

	private static ResourceBundle rb = ResourceBundle
			.getBundle("org.ultimania.middlegenide.core.ResourceMessages");

	public DatabaseInfo(Class driverClass) throws InstantiationException,
			IllegalAccessException {
		driver = (Driver) driverClass.newInstance();
	}

	public void setURI(String uri) {
		this.uri = uri;
	}

	public void setCatalog(String catalog) {
		this.catalog = catalog;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public void setSchema(String schema) {
		this.schema = schema;
	}

	public void setUser(String user) {
		this.user = user;
	}

	public void enableView(boolean flag) {
		enableView = flag;
	}

public ArrayList loadTable() throws SQLException {
		ArrayList list = new ArrayList();

		Properties p = new Properties();
		p.setProperty("user", user);
		p.setProperty("password", password);

		Connection con = null;
		try {
			con = driver.connect(uri, p);
			if (con == null)
				throw new SQLException(rb.getString(Resource.ERROR_CONNECTION));
			DatabaseMetaData meta = con.getMetaData();
			productName = meta.getDatabaseProductName();
			if (isMSSQL()) {
				if (catalog.length() == 0) {
					catalog = "%";
				}
			}

			catalog = (catalog.length() == 0) ? null : catalog;
			schema = (schema.length() == 0) ? null : schema;
			ResultSet tables = meta.getTables(catalog, schema, "%",
					isOracle() ? new String[] { "TABLE", "VIEW", "SYNONYM" }
							: null);
			while (tables.next()) {

				String t = tables.getString("TABLE_TYPE");
				if ("TABLE".equals(t) || ("VIEW".equals(t) && enableView)
						|| (isOracle() && "SYNONYM".equals(t))) {
					list.add(tables.getString("table_name"));
				}
			}

			tables.close();

			if (driver.getClass().getName().equals("org.hsqldb.jdbcDriver")
					&&uri.indexOf("jdbc:hsqldb:hsql://")!=0) {
				Statement stmt = null;

				try {
					stmt = con.createStatement();
					System.out.println("SHUTDOWN");
					System.out.println(uri);
					stmt.executeUpdate("SHUTDOWN;");
				} finally {
					if(stmt!=null)
						stmt.close();
				}
			}
		} finally {
			if (con != null)
				con.close();
		}
		return list;

	}	
	public String getProductName() {
		return productName;
	}

	public boolean isPostgreSQL() {
		return POSTGRESQL.equals(productName);
	}

	public boolean isMySQL() {
		return MYSQL.equals(productName);
	}

	public boolean isHSQLDB() {
		return HSQLDB.equals(productName);
	}

	public boolean isDerby() {
		return DERBY.equals(productName);
	}

	public boolean isMSSQL() {
		if (productName.toLowerCase().indexOf("microsoft") != -1) {
			return true;
		} else {
			return false;
		}
	}

	public boolean isOracle() {
		if (productName.toLowerCase().indexOf("oracl") != -1) {
			return true;
		} else {
			return false;
		}
	}

	public void writeResultColumns(ResultSet cols) throws SQLException {
		ResultSetMetaData m = cols.getMetaData();
		int c = m.getColumnCount();

		while (cols.next()) {
			for (int k = 1; k < (c + 1); k++) {
				System.out
						.println(m.getColumnName(k) + ":" + cols.getString(k));
			}
		}
	}

	public static void main(String args[]) throws ClassNotFoundException,
			InstantiationException, IllegalAccessException, SQLException {
		Class driver = Class.forName(args[0]);
		DatabaseInfo di = new DatabaseInfo(driver);
		di.setURI(args[1]);
		di.setUser(args[2]);
		di.setPassword(args[3]);
		System.out.println(di.loadTable());
		System.out.println("Product Name = \"" + di.getProductName() + "\"");
	}
}